import { CoreTask } from '../../../external/task/core-task.js';
import { LogType } from '../enum/log-type.js';
import { PoolState } from '../enum/pool-state.js';
import { Log } from '../log-collection/log.js';
import { TCB } from '../model/tcb.js';

import { SubmitOption } from './submit-option.js';
import { WorkerPool } from './worker-pool.js';
import { WorkerPoolFactory } from './worker-pool-factory.js';

/**
 * 工作池代理器
 * 内置于task的对象，提供对工作池功能的间接访问
 *
 * @since 2022/8/31
 */
export class WorkerPoolDelegator {
  private workerPool: () => WorkerPool;
  private static isActive = false;
  private static needWarmUp = false; // 暂时不启用

  constructor() {
    let innerPool: WorkerPool | undefined;
    this.workerPool = () => {
      WorkerPoolDelegator.isActive = true;
      return innerPool ?? (innerPool = WorkerPoolFactory.getDefaultWorkerPool());
    };
  }

  warmUp(warmUpPath: string): void {
    if (WorkerPoolDelegator.needWarmUp) {
      const cnt = this.workerPool().getMinPoolNum();
      for (let i = 0; i < cnt; i++) {
        this.workerPool().warmUp(warmUpPath);
      }
      WorkerPoolDelegator.needWarmUp = false;
    }
  }

  submit(task: CoreTask, workPath: string, submitOption?: SubmitOption): TCB {
    return this.workerPool().submit(task, workPath, submitOption);
  }

  async terminate(): Promise<boolean> {
    const isTerminated = await this.workerPool().terminate();
    WorkerPoolDelegator.isActive = !isTerminated;
    return isTerminated;
  }

  getState(): PoolState {
    return this.workerPool().getState();
  }

  setState(state: PoolState): void {
    this.workerPool().setState(state);
  }

  setRecycleInterval(recycleInterval: number): void {
    this.workerPool().setRecycleInterval(recycleInterval);
  }

  setMaxIdleTime(maxIdleTime: number): void {
    this.workerPool().setMaxIdleTime(maxIdleTime);
  }

  setErrorCallback(errorCallback: Function): void {
    this.workerPool().setErrorCallback(errorCallback);
  }

  getLog(type: LogType): Set<Log> | undefined {
    return this.workerPool().getLog(type);
  }

  clearLog(type?: LogType): void {
    this.workerPool().clearLog(type);
  }

  getMaxPoolNum(): number {
    return this.workerPool().getMaxPoolNum();
  }

  getMinPoolNum(): number {
    return this.workerPool().getMinPoolNum();
  }

  setResident(resident: boolean): void {
    this.workerPool().setResident(resident);
  }

  isActive() {
    return WorkerPoolDelegator.isActive;
  }
}
